/*
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *
 *   版权所有  2014-2015 成都星锐蓝海网络科技有限公司
 *   商业许可请联系  +86-18682011860    QQ:66442834
 *   
 */

#include <pthread.h>
#include "xyz_int.h"
#include "xyz_log.h"

#include "nsap_dscv_addr.h"

#include "util.h"
#include "wtpinfo.h"
#include "udphelp.h"
#include "wmp.h"
#include "wmpctrl.h"
#include "global.h"

extern int G_wmpsock;
extern struct sockaddr_in G_wmpaddr;
extern uint16_t wtpInfoGetSEQNUM(void);
 void *nsap_firm_upgr_thread_func(void *arg);


typedef struct {
	xyz_u8_t sessid[256];
	xyz_u8_t length;
} nsap_firm_seeid_t;


static int nsap_firm_upgr_error(unsigned int code);
static nsap_firm_seeid_t S_firm_sessid;

int nsap_firm_set_sessid(unsigned char *id, unsigned char len)
{
	memcpy(S_firm_sessid.sessid, id, len);
	S_firm_sessid.length = len;
	return 0;
}

int nsap_firm_upgr_thread(void)
{
	pthread_t pid;
	if (pthread_create(&pid, NULL, nsap_firm_upgr_thread_func, NULL)) {
		xyz_log_error("ceate firm upgrade thread failed");
		return -1;
	}
	return 0;
}

 void *nsap_firm_upgr_thread_func(void *arg)
{
	const char *host = nsap_dscv_addr_get_addr();
	const char *port = NSWMP_IMGDWN_PORT;
//	const char *apid = nsap_deid_get_string();
        const char *apid = devid;
	const char *savefile = "/tmp/firmware.bin";
	const char sessid[256] = { 0 };
	int rc = 0;
return ;
        
	while (1) {
		do {
			rc = xyz_hex_byte_upper(S_firm_sessid.sessid, S_firm_sessid.length, sessid, sizeof(S_firm_sessid.sessid));
			if (rc >= sizeof(sessid)) {
				xyz_log_error("Firmware-Session-Id to string failed");
				nsap_firm_upgr_error(42);
				rc = -1;
				break;
			}

			// rc = nsap_firm_get_file(host, port, apid, sessid, savefile);
			if (rc != 0) {
				xyz_log_error("Down Firmware file failed");
				nsap_firm_upgr_error(rc);
				rc = -1;
				break;
			}

			rc = nsap_firm_test_file(savefile);
			if (rc != 0) {
				xyz_log_error("Test Firmware file failed");
				nsap_firm_upgr_error(rc);
				rc = -1;
				break;
			}

			rc = nsap_firm_flash_file(savefile);
			if (rc != 0) {
				xyz_log_error("Flash Firmware file failed");
				nsap_firm_upgr_error(rc);
				rc = -1;
				break;
			}
			xyz_log_debug("Upgrade OK, will reboot");
			utilDoCMD("reboot");
		} while (0);
		if (rc != 0) {
			/*  睡眠1分钟    */
			sleep(60);
		} else {
			break;
		}
	}

}

void nsap_firm_upgr(int *state)
{
	const char *host = nsap_dscv_addr_get_addr();
	const char *port = NSWMP_IMGDWN_PORT;
//	const char *apid = nsap_deid_get_string();
        const char *apid = devid;
	const char *savefile = "/tmp/firmware.bin";
	const char sessid[256] = { 0 };
	int rc = 0;
return;
        
	rc = xyz_hex_byte_upper(S_firm_sessid.sessid, S_firm_sessid.length, sessid, sizeof(S_firm_sessid.sessid));
	if (rc >= sizeof(sessid)) {
		xyz_log_error("Firmware-Session-Id to string failed");
		nsap_firm_upgr_error(42);
		if (state) {
			*state = WTP_STATE_SULK;
		}
		return;
	}

//	rc = nsap_firm_get_file(host, port, apid, sessid, savefile);
	if (rc != 0) {
		xyz_log_error("Down Firmware file failed");
		nsap_firm_upgr_error(rc);
		if (state) {
			*state = WTP_STATE_SULK;
		}
		return;
	}

	rc = nsap_firm_test_file(savefile);
	if (rc != 0) {
		xyz_log_error("Test Firmware file failed");
		nsap_firm_upgr_error(rc);
		if (state) {
			*state = WTP_STATE_SULK;
		}
		return;
	}

	rc = nsap_firm_flash_file(savefile);
	if (rc != 0) {
		xyz_log_error("Flash Firmware file failed");
		nsap_firm_upgr_error(rc);
		if (state) {
			*state = WTP_STATE_SULK;
		}
		return;
	}
	xyz_log_debug("Upgrade OK, will reboot");
	utilDoCMD("reboot");
}

/*
 *
 */
static int nsap_firm_upgr_error(unsigned int code)
{
	WMMSG msg;
	BUFF attr = BUFF_INIT;
	uint16_t seqnum = 0;
	uint8_t *apid = NULL;

	wmmPackResCode(&attr, code);
//	apid = (uint8_t *)nsap_deid_get_byte();
        apid  = (uint8_t *)devid;
	seqnum = wtpInfoGetSEQNUM();
	if (wmmClearInit(&msg, apid, seqnum, WMM_CODE_IMGUP_REP)) {
		xyz_log_error("Message head INIT error");
		return -1;
	}
	if (wmmPutAttrBuff(&msg, &attr)) {
		xyz_log_error("Put attribute error");
		return -1;
	}
	if (udpSend(G_wmpsock, msg.buff, msg.offset, &G_wmpaddr) < 1) {
		xyz_log_error("sendto : %s", strerror(errno));
		return -1;
	}
	return 0;
}
